// 环境配置
const env = 'production'; // 切换环境：development/test/production
// basic-api/
// 基础地址配置
const baseUrls = {
  development: 'http://10.1.21.250:18080/',
  // test: 'https://ai.srcszj.com.cn:5090/prod-api/',
  production: 'https://yzyw.srcszj.com.cn:1005/prod-api/'
};

// 当前环境的基础地址
const baseUrl = baseUrls[env];
// 全局状态管理（增加登录页路径配置）
const requestState = {
  isAuthenticated: true,
  pendingRequests: new Map(),
  loginPagePath: '/pages/index/index', // 登录页路径，与重定向路径一致
  // 登录相关接口列表（允许在认证失败时访问）
  authWhitelist: [
    'auth/login', // 登录接口
  ]
};

// 获取token
function getToken() {
  try {
    // 获取本地存储：my.getStorageSync，返回格式含data字段
    const storageRes = my.getStorageSync({
      key: 'token'
    })
    return storageRes.data ? storageRes.data : '';
  } catch (error) {
    console.error('获取token失败:', error);
    return '';
  }
}
/**
 * 处理认证失败：清除token并重定向到登录页
 */
function handleAuthFailure() {
  try {
    my.removeStorageSync({
      key: 'token'
    });

    my.redirectTo({
      url: '/pages/index/index'
    });

    console.log('认证失败，已重定向到登录页');
  } catch (error) {
    console.error('处理认证失败时出错:', error);
  }
}
/**
 * 将对象转换为URL查询字符串
 * @param {Object} params - 需要转换的参数对象
 * @returns {string} 转换后的查询字符串（如 "a=1&b=2"）
 */
function objToQueryString(params) {
  if (!params || typeof params !== 'object') return '';

  const queryParams = [];
  // 遍历参数对象，拼接key=value
  Object.keys(params).forEach(key => {
    // 过滤值为undefined或null的参数
    if (params[key] !== undefined && params[key] !== null) {
      // 对参数值进行URL编码，避免特殊字符问题
      queryParams.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`);
    }
  });

  return queryParams.length > 0 ? `?${queryParams.join('&')}` : '';
}

/**
 * 请求封装
 * @param {Object} options - 请求参数
 * @param {string} options.url - 接口路径（相对于baseUrl）
 * @param {string} options.method - 请求方法，默认GET
 * @param {Object} options.data - 请求数据
 * @param {Object} options.headers - 自定义请求头
 * @param {boolean} options.showLoading - 是否显示加载提示，默认true
 * @returns {Promise} - 返回Promise对象
 */
function request(options) {
  const {
    url,
    method = 'GET',
    data = {},
    headers = {},
    params = {},
    showLoading = true
  } = options;

  // 显示加载提示
  if (showLoading) {
    my.showLoading({
      content: '加载中...',
      mask: true
    });
  }

  // 拼接完整请求地址
  let fullUrl = `${baseUrl}${url}`;
  if (method.toUpperCase() === 'GET') {
    // 拼接查询字符串到URL
    const queryString = objToQueryString(params);
    fullUrl = `${fullUrl}${queryString}`;
  }
  // 强制处理POST/PUT请求的data为JSON字符串（确保格式正确）&& 排除特殊接口例如登录接口
  let requestData = data;
  if (['POST', 'PUT'].includes(method.toUpperCase()) && !requestState.authWhitelist.some(item => url.includes(item))) {
    // 若data是对象，转为JSON字符串；若已是字符串，尝试验证是否为合法JSON
    if (typeof data === 'object') {
      requestData = JSON.stringify(data);
    } else if (typeof data === 'string') {
      try {
        JSON.parse(data); // 验证是否为合法JSON
      } catch (e) {
        console.error('传入的data字符串不是合法JSON，已自动转换');
        requestData = JSON.stringify({
          data: data
        }); // 兜底处理
      }
    }
  }

  const token = getToken();

  // 默认请求头
  const defaultHeaders = {
    'Content-Type': 'application/json',
    'clientId': "e5cd7e4891bf95d1d19206ce24a7b32e",
    // 可添加全局默认headers，如token等
    // 'Authorization': `Bearer ${getToken()}`
    // 登录后自动添加Authorization：Bearer + token（无token则不添加该字段）
    ...(token ? {
      'Authorization': `Bearer ${token}`
    } : {})
  };

  // 合并请求头
  const requestHeaders = {
    ...defaultHeaders,
    ...headers
  }

  return new Promise((resolve, reject) => {
    // console.log(requestData)
    my.httpRequest({
      url: fullUrl,
      method,
      data: requestData,
      headers: requestHeaders,
      dataType: 'json',
      timeout: 10000,
      success: (res) => {
        if (showLoading) {
          my.hideLoading();
        }
        // 检查是否是认证失败
        if (res.data.msg === "认证失败，无法访问系统资源") {
          handleAuthFailure();
          return reject(new Error("认证失败，已重定向到登录页"));
        }
        // 处理HTTP状态码
        if (res.status === 200) {
          // 业务逻辑成功
          if (res.data.code === 200) {
            if (res.data.data) {
              resolve(res.data.data);
            } else if (res.data.rows && res.data.total) {
              const data = {
                rows: res.data.rows,
                total: res.data.total
              }
              resolve(data);
            } else {
              resolve(res.data);
            }
          } else {
            // 业务逻辑错误
            my.showToast({
              content: res.data.msg || "操作失败",
              type: "none",
              duration: 2000
            });
            reject(new Error(res.data.msg || "业务处理失败"));
          }
        } else {
          if (res.data.msg === "认证失败，无法访问系统资源") {
            handleAuthFailure();
            return reject(new Error("认证失败，已重定向到登录页"));
          }
          // HTTP错误
          my.showToast({
            content: `请求失败: ${res.data.msg}`,
            type: 'fail',
            duration: 2000
          });
          reject(new Error(`HTTP错误: ${res.data.msg}`));
        }
      },
      fail: (err) => {

        if (showLoading) {
          my.hideLoading();
        }

        // 网络错误
        my.showToast({
          content: '网络异常，请稍后重试',
          type: 'fail',
          duration: 2000
        });
        reject(err);
      }
    });
  });
}

function getImageStream(url, header) {
  const fullUrl = `${baseUrl}${url}`;
  const downloadUrl = fullUrl.includes('?') ?
    `${fullUrl}&_t=${Date.now()}${Math.random().toString(36).slice(2, 8)}` :
    `${fullUrl}?_t=${Date.now()}${Math.random().toString(36).slice(2, 8)}`;

  return new Promise((resolve, reject) => {
    const token = getToken();

    const defaultHeaders = {
      'Content-Type': 'application/octet-stream;charset=UTF-8',
      'clientId': "e5cd7e4891bf95d1d19206ce24a7b32e",
      ...(token ? {
        'Authorization': `Bearer ${token}`
      } : {})
    };

    // var tmpPath = my.env.USER_DATA_PATH + '/img_' + Date.now() + '.png';

    // console.log('[downloadFile]', fullUrl);
    my.downloadFile({
      url: downloadUrl,
      header: defaultHeaders,
      success: res => {
        // console.log('[downloadFile success]', res);
        resolve(res.apFilePath);
      },
      fail: err => {
        console.error('[downloadFile fail]', err);
        reject(err);
      }
    });
  });
}

/**
 * 导出Excel文件（处理二进制流）
 * @param {Object} options - 导出配置参数
 * @param {string} options.url - 导出接口地址（必填）
 * @param {string} [options.method='GET'] - 请求方式（GET/POST）
 * @param {Object} [options.data={}] - 请求参数（GET拼url，POST传body）
 * @param {Object} [options.headers={}] - 自定义请求头（如特殊token、编码）
 * @param {string} [options.fileName='导出数据.xlsx'] - 保存的文件名（默认带xlsx后缀）
 * @returns {Promise} - 导出结果Promise
 */
export const exportExcel = async (options = {}) => {
  const token = getToken();
  // 1. 基础配置：强制二进制接收，避免JSON解析错误
  const defaultExportOptions = {
    method: 'GET',
    headers: {
      // 导出接口可能需要的头（覆盖普通接口的JSON头，避免后端返回格式错误）
      'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      ...(token ? {
        'Authorization': `Bearer ${token}`
      } : {})
    },
    data: {},
    fileName: '导出数据.xlsx', // 默认文件名
    responseType: 'arraybuffer', // 核心：强制二进制接收，必须设置！
    url: '' // 接口地址必填，未传则报错
  };

  // 2. 合并用户配置（用户配置优先级高于默认）
  const finalOptions = {
    ...defaultExportOptions,
    ...options
  };

  // 3. 校验必填参数
  if (!finalOptions.url) {
    my.showToast({
      content: '导出接口地址url不能为空',
      type: 'fail'
    });
    return Promise.reject(new Error('url is required'));
  }

  try {
    // 4. 调用基础请求（此时已强制arraybuffer，不会走JSON解析）
    const response = await my.httpRequest(finalOptions);

    // 5. 校验接口响应（状态码200且有二进制数据）
    if (response.status !== 200 || !response.data) {
      throw new Error(`接口返回异常，状态码: ${response.status}，错误信息: ${response.errorMessage || '无'}`);
    }

    // 6. 二进制数据转Base64（钉钉saveFile需要Base64格式）
    const base64Data = my.arrayBufferToBase64(response.data);

    // 7. 保存文件到本地
    const saveRes = await my.saveFile({
      fileName: finalOptions.fileName, // 自定义文件名
      base64Data: base64Data // 转换后的Base64数据
    });

    // 8. 保存成功后自动打开文件（可选，用户体验更好）
    // await my.openDocument({
    //   filePath: saveRes.filePath, // 保存后的文件路径
    //   fileType: 'xlsx', // 文件类型（Excel固定为xlsx）
    //   success: () => {
    //     my.showToast({
    //       content: `文件已打开: ${finalOptions.fileName}`,
    //       duration: 2000
    //     });
    //   }
    // });

    // 9. 导出成功，返回文件信息（供外部后续处理）
    return {
      success: true,
      filePath: saveRes.filePath,
      fileName: finalOptions.fileName
    };

  } catch (err) {
    // 10. 异常兜底处理（分场景提示）
    let errorMsg = '文件导出失败，请重试';
    if (err.message.includes('url is required')) {
      errorMsg = '导出接口地址不能为空';
    } else if (err.message.includes('接口返回异常')) {
      errorMsg = err.message;
    } else if (err.errorMessage) {
      errorMsg = `导出失败: ${err.errorMessage}`;
    }

    // 显示错误提示
    my.showToast({
      content: errorMsg,
      type: 'fail',
      duration: 3000
    });
    return Promise.reject(new Error(errorMsg));
  }
};


// 快捷方法封装
const http = {
  getImageStream: getImageStream,
  get(url, params = {}, headers = {}, options = {}) {
    return request({
      ...options,
      url,
      headers,
      params,
      method: 'GET'
    });
  },
  post(url, data, headers = {}, options = {}) {
    return request({
      ...options,
      url,
      headers,
      method: 'POST',
      data
    });
  },
  put(url, data, headers = {}, options = {}) {
    return request({
      ...options,
      url,
      headers,
      method: 'PUT',
      data
    });
  },
  delete(url, headers = {}, options = {}) {
    return request({
      ...options,
      url,
      headers,
      method: 'DELETE'
    });
  },
  uploadLocalImage(url, localPath) {
    return new Promise((resolve, reject) => {
      my.uploadFile({
        url: `${baseUrl}${url}`,
        filePath: localPath,
        fileName: 'file',
        fileType: 'image',
        header: {
          Authorization: `Bearer ${getToken()}`,
          clientId: 'e5cd7e4891bf95d1d19206ce24a7b32e'
        },
        success: (res) => {
          try {
            const data = JSON.parse(res.data);
            if (data.code === 200) resolve(data.data);
            else {
              my.showToast({
                content: data.msg || '上传失败',
                type: 'fail'
              });
              reject(new Error(data.msg || '上传失败'));
            }
          } catch (e) {
            reject(new Error('返回数据解析失败'));
          }
        },
        fail: (err) => {
          my.showToast({
            content: '上传失败，请重试',
            type: 'fail'
          });
          reject(err);
        }
      });
    });
  },
  export (url, params = {}, fileName = '工单信息导出.xlsx') {
    return exportExcel({
      url,
      method: 'POST',
      data: params,
      fileName: fileName
    });
  },
};

export default http
export {
  http,
  baseUrls
}